(function(context) {
    "use strict";  // jshint ;_;
      	
	if(!Function.prototype.bind) {
		Function.prototype.bind = function(ctx){
			var func = this;
			return function(){
				func.apply(ctx, arguments);
			};
		};
	}
	
	var melon =  context.melon = (context.melon || {});
    melon.namespace = function(name, obj, ctx) {
        if ( typeof name !== 'string') {
            obj && ( name = obj);
            return name;
        }
        var root = ctx || window, 
        	parts = name.split('.'), 
        	ln = parts.length - 1, 
        	leaf = parts[ln], 
        	i, part;

    	for ( i = 0; i < ln; i++) {
            part = parts[i];
            root = root[part] || (root[part] = {});
        }

        return (root[leaf] = obj || {});
    };
    

	/**
	 * 
	 * @param {Object} obj
	 * @param {Object} cb
	 * @param {Object} ctx
	 */
    melon.each = function(obj, cb, ctx) {
		if (!obj) return;
		var hasOwn = melon.hasOwn;
		
		if (obj.push) {
			for(var i = -1, item; item = obj[++i]; ) {
				if (cb.call(ctx || obj, item, i, obj) === false) return;
			}
		} else {
			for(var k in obj) {
				if (hasOwn(obj, k)) {
					if (cb.call(ctx || obj, obj[k], k, obj) === false) return;
				} 
			}
		}
	};
	
	/**
	 * 
	 * @param {Object} obj
	 */
    melon.extend = function(obj) {
        this.each([].slice.call(arguments, 1), function(source) {
            if (source) {
                for (var prop in source) {
                    obj[prop] = source[prop];
                }
            }
        });
        return obj;
    };  
    
    melon.define = function(name, uses, func) {
    	var alen = arguments.length,
    		toStr = Object.prototype.toString;
    		
    	if (alen === 1) {
    		func = name, name = '', uses = [];
    	} else if (alen === 2) { 
    		if (toStr.call(name) === '[object Array]') {
    			func = uses, uses = name, name = ''; 
    		} else {
    			func = uses, uses = [];
    		}
    	}    	
       
       	var root = melon,
       		names = name.split('.'),
       		ln = names.length,
       		args = (function() {
       			var results = [];
       			melon.each(uses, function(module) {
       				var names = module.split('.'),
       					rut = root,
       					len = names.length,
       					cnt = 0;
	       			melon.each(names, function(name) {
	       				rut = rut[name], cnt++;
	       			});
	       			if(cnt === len) {
	       				results.push(rut);
	       			}
	       		});
	       		return results;
	       	})(),
       		attr = toStr.call(func) === '[object Function]' ? func.apply(melon, args) : func;

		name && melon.each(name.split('.'), function(name) {
			root = root[name], cnt++;
		});
       	return this;
   	};
   
   	melon.require = function(uses, func) {
   		
   	};
   	
}(window));

(function(context) {  
    "use strict";
    
    var melon = context.melon,
    	siteConfig		   = context.siteConfig,
    	ArrayProto		   = Array.prototype,
  		FuncProto		   = Function.prototype,
  		ObjProto		   = Object.prototype,
	    nativeIsArray      = Array.isArray,
	    nativeKeys         = Object.keys,
	    nativeBind         = FuncProto.bind;
    
    // core
    melon.define({
        /**
         * 
         * @param {Mix} value
         */
        toString: function() {
           var toStr = ObjProto.toString;
           return function(value) {
               return toStr.call(value);
           };
        }(),
        /**
         * 
         * @param {Object} obj
         * @param {String} name 
         */
        hasOwn: function() {
            var own = ObjProto.hasOwnProperty;
            return function(obj, name) {
                return own.call(obj, name);
            };
        }(),
        
        /**
         * 
         * @param {Object} obj
         */
        shuffle: function(obj) {
    	    var rand,
    	    	index = 0,
    	    	shuffled = [];
    	    each(obj, function(value) {
    	      rand = melon.random(index++);
    	      shuffled[index - 1] = shuffled[rand], shuffled[rand] = value;
    	    });
    	    return shuffled;
    	},
    	/**
    	 * 
    	 */
    	random: function(min, max) {
    	    if (max == null) {
    	      max = min;
    	      min = 0;
    	    }
    	    return min + Math.floor(Math.random() * (max - min + 1));
    	}
    });
            
        
    // configer
    melon.define({
        _configs: {},
        setRoot: function(ctx) {
            this._configs = ctx;
        },
        getConfig: function(name, def){
        	var root = melon._configs,
        		names = name.split('.'),
        		pair = root;
        	for(var i = 0, len = names.length; i < len; i++) {
        		if (!(pair = pair[names[i]])) {
        			return def;
        		}
        	}
        	return pair;
        },
        
        setConfig: function(name, value) {
        	var root = melon._configs,
        		names = name.split('.'),
        		len = names.length,
        		last = len - 1,
        		pair = root;
        	for(var i = 0; i < last; i++) {
        		pair = pair[names[i]] || (pair[names[i]] = {});
        	}	
        	return pair[names[last]] = value;    	
        }
    });
        
    // cookie
    melon.define({
        cookie: function(key, value, options) {
            if (arguments.length > 1 && (!/Object/.test(melon.toString(value)) || value === null || value === undefined)) {
                options = melon.extend({}, options);
    
                if (value === null || value === undefined) {
                    options.expires = -1;
                }
    
                if (typeof options.expires === 'number') {
                    var days = options.expires, t = options.expires = new Date();
                    t.setDate(t.getDate() + days);
                }
    
                value = String(value);
    
                return (document.cookie = [
                    encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
                    options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                    options.path    ? '; path=' + options.path : '',
                    options.domain  ? '; domain=' + options.domain : '',
                    options.secure  ? '; secure' : ''
                ].join(''));
            }
    
            options = value || {};
            var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
    
            var pairs = document.cookie.split('; ');
            for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
                if (decode(pair[0]) === key) return decode(pair[1] || ''); 
            }
            
            return null;
        }
    });
    
    
   	melon.define('Class', function() {
   		var Clazz = {};
   		Clazz.define = function(ns, attr) {
	     	var hasProp = Object.prototype.hasOwnProperty,
	     		emptyFn = function(){ },
	     		supr, members, statics, singleton, Parent, instance, hasNS = true;
			attr || ( hasNS = false, attr = ns);
			if (typeof attr === 'function') {
				attr = attr();
			}
			
			supr = attr.extend || emptyFn;
			singleton = attr.$singleton || false;
			statics = attr.$statics || false;
			Parent = emptyFn;
			
			melon.each(['$singleton', '$statics', 'initialize'], function(i, value) {
				delete attr[value];
			});
			
			Parent.prototype = supr.prototype;
			var Class = function() {
				if (singleton) {
					if (instance) {
						return instance;
					} else {
						instance = this;
					}
				}
			
				if (this.initialize) {
					this.initialize.apply(this, arguments);
				} else {
					supr.prototype.initialize && supr.prototype.initialize.apply(this, arguments);
				}
			};
			
			Class.superclass = Parent.prototype;
			Class.prototype = new Parent();
			Class.prototype.constructor = Class;
			
			if (singleton) {
				Class.getInstance = function() {
					if (!instance) {
						instance = new Class();
					}
					return instance;
				}
			}
			Class.prototype.proxy = function(func) {
				var _this = this;
				return function() {
					func.apply(_this, [].slice.call(arguments));
				};
			};
			
			Class.members = function(o) {
				for (var k in o) {
					if (hasProp.call(o, k)) {
						this.prototype[k] = o[k];
					}
				}
			};
			members && Class.members.call(Class, members);
			
			Class.statics = function(o) {
				o = o || {};
				for (var k in o) {
					Class[k] = o[k];
				}
				return Class;
			};
			statics && Class.statics.call(Class, statics);
			
			Class.extend = function(name, attr) {
				if(!attr) {
					attr = name;
					name = false;
				}
				attr.extend = Class;
				return melon.Class.define(name, attr);
			}
			
			hasNS && melon.namespace(ns, Class);
			return Class;
		};
		
		return Clazz;
   });

	melon.define('Listener', function(){
		var Listener = function(){};
		Listener.prototype = {
			/**
			 * 
			 * @param {Object} name
			 * @param {Object} cb
			 * @param {Object} ctx
			 */
			on: function(name, cb, ctx) {
				var lsn = this._listeners || (this._listeners = {});
				(lsn[name] || (lsn[name] = [])).push({callback: cb, context: ctx || this});
				return this;
			},
			once: function(name, cb, ctx) {
				var self = this,
					once;
				return self.on(name, (once = function() {
					self.off(name, once);
					return cb.apply(self, arguments);
				}), context);
			},
			off: function(name, cb) {
				var lsn = this._listeners;
				if (!cb) { delete lsn[name]; }			
				melon.each(lsn[name], function(value, i, list) {
					if (cb === value.callback) {
						list.splice(i, 1);
						return false;
					}
				});
				if (lsn[name].length === 0) { delete lsn[name]; } 
				return this;
			},
			trigger: function(name) {
				if (!(name in this._listeners)) return;
				var lsn = this._listeners[name],
					args = ArrayProto.splice.call(arguments, 1);
				
				melon.each(lsn, function(item) {
					item.callback.apply(item.context, args);
				});
				return this;
			}
		};
		
		return Listener;
	});
	
    // melon.PubSub
    melon.define('PubSub', (function(){
        var topics = {},     
            lastUid = -1;
     
        var publish = function( topic , data){   
            if ( !topics.hasOwnProperty( topic ) ){  
                return false;    
            }        
     
            var notify = function(){     
                var subscribers = topics[topic],     
                    throwException = function(e){    
                        return function(){       
                            throw e;         
                        };       
                    };             
     
                for ( var i = 0, j = subscribers.length; i < j; i++ ){ 
                    try {
                       subscribers[i].func( topic, data );   
                    } catch( e ){    
                        setTimeout( throwException(e), 0);   
                    }    
                }    
            };
     
            setTimeout( notify , 0 );
            return true;     
        };
        	        
	    return {
	        publish: function( topic, data ){	 
    	        return publish( topic, data, false );	 
    	    },
    	 
    	    subscribe: function( topic, func ){	 
    	        if ( !topics.hasOwnProperty( topic ) ){	 
    	            topics[topic] = [];	 
    	        }	 
    	        var token = (++lastUid).toString();	 
    	        topics[topic].push( { token : token, func : func } );
    	        return token;	 
    	    },
    	 
    	    unsubscribe: function( token ){
    	        for ( var m in topics ){
    	            if ( topics.hasOwnProperty( m ) ){
    	               for ( var i = 0, j = topics[m].length; i < j; i++ ){	 
    	                    if ( topics[m][i].token === token ){	 
    	                        topics[m].splice( i, 1 );	 
    	                        return token;	 
    	                    }	 
    	                }	 
    	            }	 
    	        }
    	        return false;
    	    }
    	};
    	
	})());
    	
    /////////////// Request Utility /////////////////////////////////
    var RequestManager = {
    	_fetchRaw: function(path, options) {
	        options = melon.extend({
	            url: path,
	            data: melon.extend({ajax: true}, options.data),
	            timeout: 30000
	        }, options);
	
	        return $.ajax(options);
	    },
	    fetchHtml: function(path, options, isStatic) {	    		
	        if (isStatic) {
	            extra_headers['X-PJAX'] = "true";
	        }
	        options = melon.extend({
	            beforeSend: function(xhr){
	                $.each(extra_headers, function(k, v){
	                    xhr.setRequestHeader(k, v);
	                });
	            },
	        }, options);
	         
	        var extra_headers = {},
	        	deferred = $.Deferred(function() {
		    		options.success && this.done(options.success);
		    		options.error && this.fail(options.error);
		    	});
		    
	        var promise = this._fetchRaw(path, options);
	         promise.done(function(data, textStatus, jqXHR) {
	    		if(textStatus === 'success') {
	    			deferred.resolve();
	    		} else {
	    			deferred.reject();
	    		}
	    	});
	    	
	    	return deferred.promise();
	    },
	    fetchData: function(path, options) {
	    	options = melon.extend({dataType: 'json'}, options);
	    	var deferred = $.Deferred(function() {
		    		options.success && this.done(options.success);
			    	options.error && this.fail(options.error);
		    	});	    	
	    	var promise = this._fetchRaw(path, options);
	    	
	    	promise.done(function(data, textStatus, jqXHR) {
	    		console.log('!!!!!!!!!', arguments);
	    		if(data.success === true) {
	    			deferred.resolve();
	    		} else {
	    			deferred.reject();
	    		}
	    	});
	    	
	    	return deferred.promise();
	    },
	    fetchStyles: (function() {            
	        var assetUrl = melon.getConfig('siteConfig.assetUrl');
	
	        function _addStylesToHead(newStyles){
	            
	            if (newStyles && newStyles.length > 0) {
	                var $newStyles = $([]);
	                $.each(newStyles, function(itm) {
	                    var link = $('<link rel="stylesheet" data-identifier="' + itm + '" href="' + assetUrl + 'css/modules/' + itm + (siteConfig.useMinifiedCss ? '.min' : '') + '.css?v=' + siteConfig.staticVersion + '">')[0];
	                    $newStyles.push(link);
	                });
	                $('head').append($newStyles);
	            }
	        }      
	        
	        return function(stylesheets){
	            var preloadedStyles = $('link[data-identifier]');
	            
	            stylesheets = arrayFilter(stylesheets, function(item){
	                var exists = true;
	                preloadedStyles.each(function(i){
	                    if(preloadedStyles.eq(i).data('identifier') == item){
	                        return exists = false, false;
	                    }
	                });
	                return exists;
	            });
	            _addStylesToHead(stylesheets);
	       };
	        
	    })()
    };
    context.RequestManager = RequestManager;

})(window);

(function(context) {
    var melon = context.melon,
        $win = $(window),
        $doc = $(document);
        
        
    
    // melon layout object
    melon.define('layout', [
    	'Class',
    	'Listener'
    ], function(Class, Listener) {
        var NS_LAYOUT = ".melonLayout", // LAYOUT EVENT NAMESPACE
            isInit = false; // singleton
            
        var Layout = Class.define({
        	singleton: true,
        	extend: Listener,
        	initialize: function(options){
        		
        	}
        });
        /*            
        return ({
            SIZES: {
               small: [0, 1024],
               medium: [1025, 1280],
               large: [1281, 1600],
               xlarge: [1601, 1000000] 
            },
            EVENTS: {
                RESIZE_END: 'resizeEnd',
                SCROLL_END: 'scrollEnd',
                MEDIAQUERY_CHANGE: 'mediaQueryChange'
            },
            DURATION: 400,
            
            init: function() {
                if (isInit) return;
                
                var that = this;
                
                $win.off(NS_LAYOUT);
                
                that._bindEndEvent('resize');
                that._bindEndEvent('scroll');
                                
                $(function(){
                    $win.triggerHandler('resize');
                    $win.triggerHandler(that.EVENTS.RESIZE_END);
                });
                
                return this;
            },
            
            _bindEndEvent: function(name) {
                var that = this,
                    timer = null,
                    prevMediaType = '';
                        
                $win.on(name + NS_LAYOUT, function(e) {               
                    var w = $doc.innerWidth();
                    
                    if(timer) {
                        clearTimeout(timer), timer = null;
                    }
                    
                    timer = setTimeout(function(){
                        $win.trigger(name + 'End');
                    }, that.DURATION);
                    
                    $.each(that.SIZES, function(key, size) {
                        var type = that.getWidthType(w);
                        if (prevMediaType != type) {
                            $win.triggerHandler(that.EVENTS.MEDIAQUERY_CHANGE, [type, prevMediaType]);
                            prevMediaType = type;
                        }
                    });
                });              
            },
            on: function() {
                $win.on.apply($win, arguments);
                
                return this;
            },    
            off: function() {
                $win.off.apply($win, arguments);
                
                return this;
            },
            trigger: function() {
                $win.trigger.apply($win, arguments);
                
                return this;
            },
            triggerHandler: function() {
                $win.triggerHandler.apply($win, arguments);
                
                return this;
            },
            getScrollTop: function() {
                return $win.scrollTop();
            },
            getDocSize: function() {
                return {width: $doc.innerWidth(), height: $doc.innerHeight()};
            },
            getWidthType: function(w) {
                w = typeof w === 'undefined' ? $doc.innerWidth() : w;
                if (w <= 1024) {
                    return 'small';
                } else if (w > 1024 && w <= 1280) {
                    return "medium";
                } else if (w > 1280 && w <= 1600) {
                    return "large";
                } else if (w > 1600) {
                    return "xlarge";
                }
                return "unknown";
            }
        }.init());
        */
    });


        
        
    melon.define('ui.NewsBox', {
    	init: function(options) {
        	if(this._isInit) return;
        	this._isInit = true;
        	
        	var that = this, // melon.ui.rightBox
        	    lay = melon.layout
        	    $right = that.$el = $(options.el);
        	    
        	//this.on(options.on || {});
        	      
            melon.layout.off('.NewsBox').on('resize.NewsBox', function() {
                if ($right.is(':visible')) {
                    var size = lay.getDocSize();
                        
                    $right.css({height: size.height - 2, left: size.width - $right.width()});
                }
            });          
	    }
    });
    
    melon.define('ui.Navigator', {
    	init: function(options) {
        	if(this._isInit) return;
        	this._isInit = true;
        	
			var that = this,
			     $header = that.$el = $(options.el);
			     			
            //this.on(options.on || {});
			    			
			melon.layout.on('scroll', function() {
				var top = melon.layout.getScrollTop();
				if(top > 200) {
					$header.css({position: 'fixed', marginTop: '', top: 0, left: 0, width: $win.innerWidth()});
				} else {
					$header.css({position: '', marginTop: 200, top: '', left: '', width: ''});
				}
			});
    	},
        on: function(){
            $win.on.apply($win, arguments);
        }
    });
    
})(window);
